/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package _bai02_phantichphankhaibao;

import java.util.ArrayList;

/**
 *
 * @author Administrator
 */
public class jClass_BoTaoCode {

    /**
     * Chuyển kiểu dữ liệu từ ngôn ngữ đặc tả sang ngôn ngữ lập trình
     * @param str_KieuDuLieuDacTa Kiểu dữ liệu ở dạng ngôn ngữ đặc tả (R, N, B, Char...)
     * @return Kiểu dữ liệu ở dạng ngôn ngữ lập trình (int, long, char...)
     */
    static jClass_PhanDacTa _phanDacTa = new jClass_PhanDacTa();
    public static String jChuyenKieuDuLieu (String str_KieuDuLieuDacTa){
        Boolean isArr = false;
        if (str_KieuDuLieuDacTa.contains("*")){
            str_KieuDuLieuDacTa = str_KieuDuLieuDacTa.replace("*", "");
            isArr = true;
        }
        String str_KetQua = "";
        str_KieuDuLieuDacTa = str_KieuDuLieuDacTa.trim();
        if (str_KieuDuLieuDacTa.equals("R"))
            str_KetQua += "float";
        else if (str_KieuDuLieuDacTa.equals("N"))
            str_KetQua += "int";
        else if (str_KieuDuLieuDacTa.equals("Char"))
            str_KetQua += "char";
        else if (str_KieuDuLieuDacTa.equals("B"))
            str_KetQua += "bool";
        else str_KetQua += "void";
        if (isArr)
            str_KetQua += "*";
        return str_KetQua;
    }public static String jChuyenKieuDuLieuCS (String str_KieuDuLieuDacTa){
        Boolean isArr = false;
        if (str_KieuDuLieuDacTa.contains("*")){
            str_KieuDuLieuDacTa = str_KieuDuLieuDacTa.replace("*", "");
            isArr = true;
        }
        String str_KetQua = "";
        str_KieuDuLieuDacTa = str_KieuDuLieuDacTa.trim();
        if (str_KieuDuLieuDacTa.equals("R"))
            str_KetQua += "Double";
        else if (str_KieuDuLieuDacTa.equals("N"))
            str_KetQua += "Int16";
        else if (str_KieuDuLieuDacTa.equals("Char"))
            str_KetQua += "Char";
        else if (str_KieuDuLieuDacTa.equals("B"))
            str_KetQua += "Boolean";
        else str_KetQua += "void";
        if (isArr)
            str_KetQua = "ArrayList";
        return str_KetQua;
    }

    /**
     * Tạo các chuổi thay thế biến dùng trong lệnh printf
     * @param str_KieuDuLieuDacTa Kiểu dữ liệu ở dạng ngôn ngữ đặc tả
     * @return chuổi thay thế cho kiểu dữ liệu (%d, %c, %f...)
     */
    public static String jTaoChuoiThayTheBienTrongLenhPrintf (String str_KieuDuLieuDacTa){
        String str_KetQua = "";
        str_KieuDuLieuDacTa = str_KieuDuLieuDacTa.trim();
        if (str_KieuDuLieuDacTa.equals("R"))
            str_KetQua += "%f";
        else if (str_KieuDuLieuDacTa.contains("N") || str_KieuDuLieuDacTa.contains("B"))
            str_KetQua += "%d";
        else if (str_KieuDuLieuDacTa.equals("Char"))
            str_KetQua += "%c";
        else if (str_KieuDuLieuDacTa.equals("String"))
            str_KetQua += "%s";
        return str_KetQua;
    }

    /**
     * Tạo các khoảng lui thích hợp cho các cấp độ cha con
     * @param i_CapDo   Cấp độ (số khoảng lui) cần tạo
     * @return  Chuổi gồm các khoảng lui
     */
    public static String jTaoCapDo (int i_CapDo){
        String str_KetQua = "";
        for (int i = 0; i < i_CapDo; i++)
            str_KetQua += jEnum_ThongTinBoSung.KhoangCachLuiGiuaChaCon.value();
        return str_KetQua;
    }

    /**
     * Tạo giá trị mặc định cho kiểu dữ liệu ví dụ: int có gtmd là 0...
     * @param str_KieuDuLieu    Kiểu dữ liệu cần tạo giá trị mặc định ở dạng ngôn ngữ đặc tả
     * @return                  Giá trị mặc định của kiểu dữ liệu
     */
    public static String jTaoGiaTriMacDinhChoKieuDuLieu (String str_KieuDuLieu){
        str_KieuDuLieu = str_KieuDuLieu.trim();
        if (str_KieuDuLieu.equals("R")||str_KieuDuLieu.equals("N")||str_KieuDuLieu.equals("Char"))
            return "0";
        else if (str_KieuDuLieu.equals("B"))
            return "true";
        else if (str_KieuDuLieu.equals("N1"))
            return "1";
        return "NULL";
    }

    /**
     * Tạo chuổi code khai báo cho biến
     * @param jB_Bien                   Biến cần tạo code khai báo
     * @param b_TaoGiaTriMacDinh        Có tạo giá trị mặc định cho biến vừa được tạo không
     * @param str_DauPhanCachPhiaSau    Dấu phân cách phía sau biến ví dụ: "," hay ";"
     * @return                          Chuổi code được tạo
     */
    public static String jTaoKhaiBaoBien (int DoLui,jClass_Bien jB_Bien, boolean b_TaoGiaTriMacDinh, String str_DauPhanCachPhiaSau){
        String str_KetQua =  jClass_BoTaoCode.jTaoCapDo(DoLui);;
        //Thêm kiểu dữ liệu và dấu phân cách
        str_KetQua += jChuyenKieuDuLieu(jB_Bien.getKieuDuLieu().trim()) + " ";
        //Thêm tên biến
        str_KetQua += jB_Bien.getTen().trim();
        if (b_TaoGiaTriMacDinh)
            //Nếu tạo giá trị mặc định
            str_KetQua += " = " + jTaoGiaTriMacDinhChoKieuDuLieu(jB_Bien.getKieuDuLieu());
        str_KetQua += str_DauPhanCachPhiaSau;
        return str_KetQua;
    }

     public static String jTaoKhaiBaoBienCS (int DoLui,jClass_Bien jB_Bien, boolean b_TaoGiaTriMacDinh, String str_DauPhanCachPhiaSau){
        String str_KetQua =  jClass_BoTaoCode.jTaoCapDo(DoLui);;
        //Thêm kiểu dữ liệu và dấu phân cách
        str_KetQua += jChuyenKieuDuLieuCS(jB_Bien.getKieuDuLieu().trim()) + " ";
        //Thêm tên biến
        str_KetQua += jB_Bien.getTen().trim();
        if (b_TaoGiaTriMacDinh)
            //Nếu tạo giá trị mặc định
            str_KetQua += " = " + jTaoGiaTriMacDinhChoKieuDuLieu(jB_Bien.getKieuDuLieu());
        str_KetQua += str_DauPhanCachPhiaSau;
        return str_KetQua;
    }

    /**
     * Tạo chuổi code khai báo có giá trị mặc định cho biến và với dấu phân cách phía sau là ";"
     * @param jB_Bien                   Biến cần tạo code khai báo
     * @return                          Chuổi code được tạo
     */
    public static String jTaoKhaiBaoBien (int DoLui,jClass_Bien jB_Bien){
        /*String str_KetQua = "";
        //Thêm kiểu dữ liệu và dấu phân cách
        str_KetQua += jChuyenKieuDuLieu(jB_Bien.getKieuDuLieu()) + " ";
        //Thêm tên biến và dấu ","
        str_KetQua += jB_Bien.getTen();
        str_KetQua += " = " + jTaoGiaTriMacDinhChoKieuDuLieu(jB_Bien.getKieuDuLieu());
        str_KetQua += ";";
        return str_KetQua;*/

        //jTaoK
        return jTaoKhaiBaoBien(DoLui,jB_Bien, true, ";");
    }

    /**
     * Tạo khai báo biến kiểu mảng
     * @param jB_Bien   Biến cần tạo khai báo
     * @return          Kết quả chuổi khai báo biến
     */
    public static String jTaoKhaiBaoBienKieuMang (jClass_Bien jB_Bien, int i_SoLuongPhanTuTrongMang){
        String str_KetQua = "";
        //Thêm kiểu dữ liệu, dấu "*" và dấu phân cách
        //Kết quả: "int* "
        str_KetQua += jChuyenKieuDuLieu(jB_Bien.getKieuDuLieu()) + "*" + " ";
        //Thêm tên biến và chuổi " = new "
        //Kết quả: "int* i"
        str_KetQua += jB_Bien.getTen() + " = new ";
        //Thêm kiểu dữ liệu và số lượng phần tử và dấu chấm phẩy
        //Kết quả "int* i = new int[4]
        str_KetQua += jB_Bien.getKieuDuLieu() + " [" + i_SoLuongPhanTuTrongMang + "];";
        return str_KetQua;
    }

    /**
     * Tạo code cho phần khai báo bao gồm giá trị trả về mặc định nếu có
     * @param jPKB_KhaiBao  Phần khai báo cần tạo code
     * @return              Đoạn code được tạo ra
     */
    public static String jTaoCodeC (jClass_PhanDacTa jPKB_DacTa){
        _phanDacTa = jPKB_DacTa;
        jClass_PhanKhaiBao jPKB_KhaiBao = _phanDacTa.getPhanKhaiBao();
        String str_KetQua = "";
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó
        int i_CapDo = 0;
        //Tạo hàm nhập giá trị các tham số
        str_KetQua += jTaoHamNhapCacThamSoC(jPKB_KhaiBao.getCacThamSo(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        //Tạo hàm xuất giá trị các tham số
        str_KetQua += jTaoHamXuatCacThamSoC(jPKB_KhaiBao.getCacThamSo(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        //Tạo hàm xuất ketqua
        str_KetQua += jTaoHamXuatKetQuaC(jPKB_KhaiBao.getGiaTriTraVe(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();
        //Ham main
        str_KetQua += jTaoHamMainC(jPKB_KhaiBao, i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        return str_KetQua;
        /*
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó
        int i_CapDo = 0;
        //Tìm kiểu dữ liệu trả về
        String str_KetQua = jTaoCapDo(i_CapDo) + jChuyenKieuDuLieu(jPKB_KhaiBao.getGiaTriTraVe().getKieuDuLieu());
        //Ghép tên hàm và mở ngoặc nhọn vào
        str_KetQua += " " + jPKB_KhaiBao.getTenHam().trim();
        str_KetQua += " ";
        //Thêm dấu "("
        str_KetQua += "(";
        //Thêm các tham số
        for (jClass_Bien jB_Bien : jPKB_KhaiBao.getCacThamSo())
            str_KetQua += jTaoKhaiBaoBien(jB_Bien, false, ",")+ " ";
        if (str_KetQua.contains(","))
            //Loại bỏ dấu "," cuối nếu có
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Thêm dấu ")" + xuống hàng
        str_KetQua += ")" + "";

        //Thêm dấu "{" + xuống hàng
        str_KetQua += jTaoCapDo(i_CapDo) + "\n{\n";
        
            //Đoạn code
            //Tăng cấp độ lên
            i_CapDo ++;
            //Tự khởi tạo giá trị trả về nếu có
            if (jPKB_KhaiBao.getGiaTriTraVe().getTen().length() != 0)
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoKhaiBaoBien(jPKB_KhaiBao.getGiaTriTraVe()) + "\n";

            str_KetQua += jTaoCapDo(i_CapDo) + "printf (\"Nhap vao tham so:\");\n";

            //Trả về
            str_KetQua += jTaoCapDo(i_CapDo) + "return";
            if (jPKB_KhaiBao.getGiaTriTraVe().getTen().length() != 0)
                str_KetQua += " " + jPKB_KhaiBao.getGiaTriTraVe().getTen();
            str_KetQua += ";\n";
        //Giảm cấp độ xuống
        i_CapDo --;
        //Thêm dấu xuống hàng và "}"
        str_KetQua += jTaoCapDo(i_CapDo) + "}";
        return str_KetQua;
        */
    }

    /**
     * Tạo một hàm main với các chức năng đơn giản như nhập, xuất tham số, nhận và xuất giá trị trả về nếu có
     * @param jPKB_KhaiBao  Phần khai báo cần tạo hàm main
     * @return              Đoạn code của hàm main vừa được tạo
     */
    public static String jTaoHamMainC (jClass_PhanKhaiBao jPKB_KhaiBao, int i_CapDo){
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó

        String str_KetQua = jTaoCapDo(i_CapDo) + "int _tmain (int argc, _TCHAR* argv[])\n";
         //Thêm dấu xuống dòng và dấu "{"
        str_KetQua += jTaoCapDo(i_CapDo) + "{\n";

    //Đoạn code
            //Tăng cấp độ
            i_CapDo ++;
        //Khởi tạo các biến
            for (jClass_Bien jB_Bien : jPKB_KhaiBao.getCacThamSo())
               str_KetQua += jTaoKhaiBaoBien(i_CapDo,jB_Bien) + "\n";
            str_KetQua += jTaoKhaiBaoBien(i_CapDo, jPKB_KhaiBao.getGiaTriTraVe())   ;
        //Gọi hàm nhập thông tin các tham số
            str_KetQua += "\n";
            ArrayList<jClass_Bien> jB_CacThamSo =jPKB_KhaiBao.getCacThamSo();
            if (jB_CacThamSo.get(0).getKieuDuLieu().contains("*")){
                 jClass_Bien jB_Bien = jB_CacThamSo.get(1);
                 str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoNhapC(jB_Bien);
                 str_KetQua += jTaoCapDo(i_CapDo) + "scanf (\"" + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu())
                            + "\",&" + jB_Bien.getTen().trim() + ");\n";
            }
            str_KetQua += jTaoCapDo(i_CapDo) + "nhapCacThamSo_"+ jPKB_KhaiBao.getTenHam() +"(";
            //Dua cac tham so vao loi goi ham
            for (int i = 0; i < jPKB_KhaiBao.getCacThamSo().size(); i++){
                jClass_Bien jB_Bien = jPKB_KhaiBao.getCacThamSo().get(i);
                str_KetQua += jB_Bien.getTen();
                if (i != jPKB_KhaiBao.getCacThamSo().size() - 1)
                    str_KetQua += ", ";
            }
            //Tạo dấu ");" và xuống dòng;
            str_KetQua += ");\n";
            str_KetQua += jTaoCapDo(i_CapDo)+ "if (KiemTraDuLieuNhap_"+ jPKB_KhaiBao.getTenHam()+"(";
              for (jClass_Bien bien : jPKB_KhaiBao.getCacThamSo()){
                //Thêm kiểu dữ liệu và ' '
               // str_KetQua += jClass_BoTaoCode.jChuyenKieuDuLieu(bien.getKieuDuLieu()) + " ";
                //Thêm tên biến và ", "
                str_KetQua += bien.getTen() + ","+
                        " ";
            //ví dụ đoạn code hiện tại "int (int a, "
               }
              if (str_KetQua.contains("," + " ")){
                 str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf("," +
                    " "));
             }

        //Thêm ') '
        str_KetQua += ")";
        //}
        str_KetQua += " == 1)\n";
            //ví dụ đoạn code hiện tại "int (int a, "
        
            str_KetQua +=  jTaoCapDo(i_CapDo + 1) + jPKB_KhaiBao.getGiaTriTraVe().getTen() + " = " + jPKB_KhaiBao.getTenHam() ;
             str_KetQua += "(";
             for (jClass_Bien bien : jPKB_KhaiBao.getCacThamSo()){
                //Thêm kiểu dữ liệu và ' '
               // str_KetQua += jClass_BoTaoCode.jChuyenKieuDuLieu(bien.getKieuDuLieu()) + " ";
                //Thêm tên biến và ", "
                str_KetQua += bien.getTen() + ","+
                        " ";
            //ví dụ đoạn code hiện tại "int (int a, "
               }
              if (str_KetQua.contains("," + " ")){
                 str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf("," +
                    " "));
             }
             
             str_KetQua += ");\n";
        //Gọi hàm xuất giá trị các tham số
             str_KetQua += jTaoCapDo(i_CapDo)+"else \n "+jTaoCapDo(i_CapDo + 1)+"printf(\"Du lieu nhap khong hop le!\");\n";
        
             str_KetQua += jTaoCapDo(i_CapDo) + "xuatKetQua_"+jPKB_KhaiBao.getTenHam()+ "(";
            //Dua cac tham so vao loi goi ham
            str_KetQua += _phanDacTa.getPhanKhaiBao().getGiaTriTraVe().getTen();
            //Tạo dấu ");" và xuống dòng;
            str_KetQua += ");\n";
            str_KetQua += jTaoCapDo(i_CapDo) + "return 0;\n";
        //Giảm cấp độ
        i_CapDo --;
        //Thêm dấu "}"
        str_KetQua += jTaoCapDo(i_CapDo) + "}";
        return str_KetQua;
        
        /*
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó
        int i_CapDo = 0;
        
        String str_KetQua = jTaoCapDo(i_CapDo) + "int _tmain (int argc, _TCHAR* argv[])\n";
        //Thêm dấu xuống dòng và dấu "{"
        str_KetQua += "{\n";

            //Đoạn code
            //Tăng cấp độ
            i_CapDo ++;
            for (jClass_Bien jB_Bien : jPKB_KhaiBao.getCacThamSo()){
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoKhaiBaoBien(jB_Bien) + "\n";
                //Tạo hàm printf thông báo nhập
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoNhap(jB_Bien);//"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                //Tạo hàm scanf nhận dữ liệu đưa vào biến
                str_KetQua += jTaoCapDo(i_CapDo) + "scanf (\"" + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu())
                        + "\",&" + jB_Bien.getTen().trim() + ");\n";
                //Tạo hàm printf xuất thông tin biến
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoGiaTriBien(jB_Bien) + jB_Bien.getTen().trim() + ");\n";

            }
        //return
        str_KetQua += jTaoCapDo(i_CapDo) + "return;\n";
        //Giảm cấp độ
        i_CapDo --;
        //Thêm dấu "}"
        str_KetQua += jTaoCapDo(i_CapDo) + "}";
        return str_KetQua;
     */
    }

    /**
     * Tạo chuổi thông báo cho người dùng nhập vào giá trị của một biến ví dụ:
     * @param jB_Bien   Biến cần được nhập vào
     * @return          Chuổi được tạo
     * Ví dụ:   printf("Nhap vao tham so X: "); \n
     */
    //CSharp

    
    public static String jTaoChuoiThongBaoNhapC (jClass_Bien jB_Bien){
        return "printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
    }

    

    /**
     * Tạo chuổi xuất thông báo giá trị của một biến lưu ý là sao khi dùng hàm này cần phải bổ sung
     * giá trị của biến và ");\n";
     * @param jB_Bien   Biến cần thông báo giá trị
     * @return          Chuổi được tạo
     * Ví dụ: printf ("Ban vua nhap cho X gia tri: %d \n",
     */
    public static String jTaoChuoiThongBaoGiaTriBienC (jClass_Bien jB_Bien){
        return "printf (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu()) + "\\n\", ";
    }

     
    /**
     * Tạo chuổi hàm xuất giá trị các tham số
     * @param jB_CacThamSo  danh sách các tham số
     * @param i_CapDo       cấp độ (độ lùi hiện tại chỉ phục vụ cho việc định dạng code cho dể nhìn :)) của hàm xuất
     * @return              chuổi được tạo
     */
    public static String jTaoHamXuatCacThamSoC(ArrayList<jClass_Bien> jB_CacThamSo, int i_CapDo){
        String str_KetQua = jTaoCapDo(i_CapDo)+" void xuatCacThamSo_"+ _phanDacTa.getPhanKhaiBao().getTenHam()+" (";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;
        for (jClass_Bien jB_Bien : jB_CacThamSo){
            str_KetQua += jChuyenKieuDuLieu(jB_Bien.getKieuDuLieu().trim()) + " &" + jB_Bien.getTen().trim() + ", ";
        }
        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            //Tạo các chuổi xuất thông báo và nhập biến
            for (jClass_Bien jB_Bien : jB_CacThamSo){
                //Tạo hàm printf xuất thông tin biến
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoGiaTriBienC(jB_Bien) /*"printf (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu()) + "\\n\","*/ + jB_Bien.getTen().trim() + ");\n";

            }
        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }
    public static String jTaoHamXuatKetQuaC(jClass_Bien KetQua, int i_CapDo){
         String str_KetQua = jTaoCapDo(i_CapDo)+" void xuatKetQua_"+ _phanDacTa.getPhanKhaiBao().getTenHam()+" (";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;

            str_KetQua += jChuyenKieuDuLieu(KetQua.getKieuDuLieu().trim())+ " " + KetQua.getTen().trim() + ", ";

        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            //Tạo các chuổi xuất thông báo và nhập biến

                //Tạo hàm printf xuất thông tin biến
       str_KetQua += jTaoCapDo(i_CapDo) + "printf (\"Ket qua "  + KetQua.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(KetQua.getKieuDuLieu()) + "\\n\", " /*"printf (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu()) + "\\n\","*/ + KetQua.getTen().trim() + ");\n";


        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }
    public static String jTaoHamNhapMangC(jClass_Bien bienMang, jClass_Bien bienDem, int CapDo){
        String Kq = jTaoCapDo(CapDo) + bienMang.getTen() + " = new " +
            jChuyenKieuDuLieu(bienMang.getKieuDuLieu().replace("*", "")) + "[" + bienDem.getTen() + " + 1];\n";

        String jBienDem = bienDem.getTen() == "i" ? "n" : "i";
        Kq += jTaoCapDo(CapDo) + "for (int " + jBienDem + " = 0; " + jBienDem + " < " + bienDem.getTen() + "; " + jBienDem + "++)\n";
        Kq += jTaoCapDo(CapDo++) + "{\n";
            jClass_Bien bien = new jClass_Bien(bienMang.getTen() + "[i]", bienMang.getKieuDuLieu().replace("*", ""));
            Kq += jTaoCapDo(CapDo) + jTaoChuoiThongBaoNhapC(bien);//"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                //Tạo hàm scanf nhận dữ liệu đưa vào biến
            Kq += jTaoCapDo(CapDo) + "scanf (\"" + jTaoChuoiThayTheBienTrongLenhPrintf(bien.getKieuDuLieu())
                    + "\",&" + bien.getTen().trim() + ");\n";
        Kq += jTaoCapDo(--CapDo) + "}\n";
        Kq += jTaoCapDo(CapDo) + bienMang.getTen() + "[" + bienDem.getTen() + "] = 0;\n";
        return Kq;
    }

    public static String jTaoHamNhapCacThamSoC(ArrayList<jClass_Bien> jB_CacThamSo, int i_CapDo){
        String str_KetQua = jTaoCapDo(i_CapDo)+"void nhapCacThamSo_" + _phanDacTa.getPhanKhaiBao().getTenHam() + "(";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;
        for (jClass_Bien jB_Bien : jB_CacThamSo){
            str_KetQua += jChuyenKieuDuLieu(jB_Bien.getKieuDuLieu().trim()) + " &" + jB_Bien.getTen().trim() + ", ";
        }
        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            if (jB_CacThamSo.get(0).getKieuDuLieu().contains("*"))
            {
                //"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                    //Tạo hàm scanf nhận dữ liệu đưa vào biến

                str_KetQua += jTaoHamNhapMangC(jB_CacThamSo.get(0), jB_CacThamSo.get(1), i_CapDo);
            }
            else
                //Tạo các chuổi nhap giá trị các tham số
                for (jClass_Bien jB_Bien : jB_CacThamSo){
                    //Tạo hàm printf thông báo nhập
                    str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoNhapC(jB_Bien);//"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                    //Tạo hàm scanf nhận dữ liệu đưa vào biến
                    str_KetQua += jTaoCapDo(i_CapDo) + "scanf (\"" + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu())
                            + "\",&" + jB_Bien.getTen().trim() + ");\n";
                }
        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }

    /**
     * Tạo chuổi hàm nhập giá trị cho các tham số
     * @param jB_CacThamSo  danh sách các tham số
     * @param i_CapDo       cấp độ (độ lùi hiện tại chỉ phục vụ cho việc định dạng code cho dể nhìn :)) của hàm nhập
     * @return              chuổi được tạo
     */
   
    /**
     * Tạo chuổi hàm nhập giá trị cho các tham số
     * @param jB_CacThamSo  danh sách các tham số
     * @param i_CapDo       cấp độ (độ lùi hiện tại chỉ phục vụ cho việc định dạng code cho dể nhìn :)) của hàm nhập
     * @return              chuổi được tạo
     */
    
    /**
     * Phát sinh code cho phần đặc tả
     * @param phanDacTa   phần đặc tả cần phát sinh code
     * @param i_CapDo     cấp độ (độ lùi hiện tại chỉ phục vụ cho việc định dạng code cho dể nhìn :)) của hàm
     * @return
     */
    public static String jTaoHamTuNgonNguDacTa (jClass_PhanDacTa phanDacTa, int i_CapDo){
        jClass_PhanKhaiBao jPKB_KhaiBao = phanDacTa.getPhanKhaiBao();
        //Lùi code và một đoạn hợp lý (dựa vào cấp độ) và thêm kiểu dữ liệu trả về và " ("
        String str_KetQua = jTaoCapDo(i_CapDo) +
                jChuyenKieuDuLieu(jPKB_KhaiBao.getGiaTriTraVe().getKieuDuLieu()) +
                " " + "(";
        //ví dụ đoạn code hiện tại: int (

        //Thêm danh sách tham số
        for (jClass_Bien bien : jPKB_KhaiBao.getCacThamSo()){
            //Thêm kiểu dữ liệu và ' '
            str_KetQua += jChuyenKieuDuLieu(bien.getKieuDuLieu()) + " ";
            //Thêm tên biến và ", "
            str_KetQua += bien.getTen() + ","+
                    " ";
            //ví dụ đoạn code hiện tại "int (int a, "
        }
        //ví dụ đoạn code hiện tại "int (int a, int b, "
        //Loại bỏ ", " dư (nếu có)
        if (str_KetQua.contains("," + " "))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf("," +
                    " "));

        //Thêm ') '
        str_KetQua += ")";
        //ví dụ đoạn code hiện tại "int (int a, int b)"
        //Thêm dấu xuống dòng, "{" và dấu xuống dòng
        str_KetQua += jTaoCapDo(i_CapDo) + "\n{\n";

        /*ví dụ đoạn code hiện tại "int (int a, int b)
         *                          {
         *                              "
         * Kể từ đây vì chỉ minh họa từng dòng code
         */

        //-------------------Đoạn code thực hiện chương trình-------------------
        //Tăng cấp độ
        i_CapDo++;
        //Khai báo biến trả về (nếu có) ví dụ: "int result = 0;\n"
        if (jPKB_KhaiBao.getGiaTriTraVe().getTen().length() != 0)
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoKhaiBaoBien(i_CapDo,jPKB_KhaiBao.getGiaTriTraVe()) + "\n";

        //Tạo phần trả về ví dụ: "return result;\"
        str_KetQua += jTaoCapDo(i_CapDo) + "return " + jPKB_KhaiBao.getGiaTriTraVe().getTen() + ";\n";
        //-----------------Kết thục đoạn code thực hiện chương trình------------

        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }
    public static String jTaoChuoiThongBaoNhapCSharp (jClass_Bien jB_Bien){
        return "Console.Write(\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
    }

    public static String jTaoChuoiThongBaoGiaTriBienCSharp (jClass_Bien jB_Bien){
       String kq = "Console.Write (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                         + "\\n\");\n " ;
       kq +=jTaoCapDo(1)+ "Console.Write(" + jB_Bien.getTen()+");\n";
       return kq;
    }

     public static String jTaoHamNhapMangCSharp(jClass_Bien bienMang, jClass_Bien bienDem, int CapDo){
        String Kq = jTaoCapDo(CapDo) + bienMang.getTen() + " = new " +
            jChuyenKieuDuLieu(bienMang.getKieuDuLieu().replace("*", "")) + "[" + bienDem.getTen() + " + 1];\n";

        String jBienDem = bienDem.getTen() == "i" ? "n" : "i";
        Kq += jTaoCapDo(CapDo) + "for (int " + jBienDem + " = 0; " + jBienDem + " < " + bienDem.getTen() + "; " + jBienDem + "++)\n";
        Kq += jTaoCapDo(CapDo++) + "{\n";
            jClass_Bien bien = new jClass_Bien(bienMang.getTen() + "[i]", bienMang.getKieuDuLieu().replace("*", ""));
            Kq += jTaoCapDo(CapDo) + jTaoChuoiThongBaoNhapCSharp(bien);//"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                //Tạo hàm scanf nhận dữ liệu đưa vào biến
            Kq += jTaoCapDo(CapDo)  + bien.getTen().trim() +"=Console.ReadLine ();\n";
        Kq += jTaoCapDo(--CapDo) + "}\n";
        Kq += jTaoCapDo(CapDo) + bienMang.getTen() + "[" + bienDem.getTen() + "] = 0;\n";
        return Kq;
    }

    public static String jTaoHamNhapCacThamSoCSharp(ArrayList<jClass_Bien> jB_CacThamSo, int i_CapDo){
        String str_KetQua = jTaoCapDo(i_CapDo)+"public static void nhapCacThamSo_"+ _phanDacTa.getPhanKhaiBao().getTenHam()+"(";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;
        for (jClass_Bien jB_Bien : jB_CacThamSo){
            str_KetQua += "ref " + jChuyenKieuDuLieuCS(jB_Bien.getKieuDuLieu().trim()) + " " + jB_Bien.getTen().trim() + ", ";
        }
        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            //Tạo các chuổi xuất giá trị các tham số
            for (jClass_Bien jB_Bien : jB_CacThamSo){
                //Tạo hàm printf thông báo nhập
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoNhapCSharp(jB_Bien);
                //"printf (\"Nhap vao tham so "  + jB_Bien.getTen().trim() + ": \");\n";
                //Tạo hàm scanf nhận dữ liệu đưa vào biến
                str_KetQua += jTaoCapDo(i_CapDo) +
                     jB_Bien.getTen().trim() + " ="+ jChuyenKieuDuLieuCS(jB_Bien.getKieuDuLieu())+".Parse("+ "Console.ReadLine());\n";
            }
        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }


    // CSharp
     public static String jTaoHamXuatCacThamSoCSharp(ArrayList<jClass_Bien> jB_CacThamSo, int i_CapDo){
        String str_KetQua = jTaoCapDo(i_CapDo)+"public static void xuatCacThamSo_"+ _phanDacTa.getPhanKhaiBao().getTenHam()+" (";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;
        for (jClass_Bien jB_Bien : jB_CacThamSo){
            str_KetQua += jChuyenKieuDuLieuCS(jB_Bien.getKieuDuLieu().trim()) + " " + jB_Bien.getTen().trim() + ", ";
        }
        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            //Tạo các chuổi xuất thông báo và nhập biến
            for (jClass_Bien jB_Bien : jB_CacThamSo){
                //Tạo hàm printf xuất thông tin biến
                str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoGiaTriBienCSharp(jB_Bien) ;/*"printf (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu()) + "\\n\","*/   

            }
        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }

     public static String jTaoHamXuatKetQuaCSharp(jClass_Bien KetQua, int i_CapDo){
         String str_KetQua = jTaoCapDo(i_CapDo)+"public static void xuatKetQua_"+ _phanDacTa.getPhanKhaiBao().getTenHam()+" (";
        //Dua cac bien can nhap vao voi tu cach la tham bien cua ham nhap;

            str_KetQua += jChuyenKieuDuLieuCS(KetQua.getKieuDuLieu().trim())+ " " + KetQua.getTen().trim() + ", ";

        if (str_KetQua.contains(","))
            str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf(","));
        //Đóng ngoặc "(" vàxuống dòng.
        str_KetQua += ")\n";
        //Tạo dấu "{" và tăng cấp độ
        str_KetQua += jTaoCapDo(i_CapDo++) + "{\n";

            //Tạo các chuổi xuất thông báo và nhập biến

                //Tạo hàm printf xuất thông tin biến
       str_KetQua += jTaoCapDo(i_CapDo) + "Console.Write (\"Ket qua "  + KetQua.getTen().trim() + " gia tri:\");\n ";
                        /*"printf (\"Ban vua nhap cho "  + jB_Bien.getTen().trim() + " gia tri: "
                        + jTaoChuoiThayTheBienTrongLenhPrintf(jB_Bien.getKieuDuLieu()) + "\\n\","*/
       str_KetQua += jTaoCapDo(i_CapDo)+"Console.Write("+KetQua.getTen().trim() + ");\n";


        //Giảm cấp độ và tạo dấu "}"
        str_KetQua += jTaoCapDo(--i_CapDo) + "}";
        return str_KetQua;
    }
      
    public static String jTaoHamMainCSharp (jClass_PhanKhaiBao jPKB_KhaiBao, int i_CapDo){
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó
        String str_KetQua = jTaoCapDo(i_CapDo) + "static void Main (string[] args)\n";
         //Thêm dấu xuống dòng và dấu "{"
        str_KetQua += jTaoCapDo(i_CapDo) + "{\n";

    //Đoạn code
            //Tăng cấp độ
            i_CapDo ++;
        //Khởi tạo các biến
            for (jClass_Bien jB_Bien : jPKB_KhaiBao.getCacThamSo())
               str_KetQua += jTaoKhaiBaoBienCS(i_CapDo,jB_Bien, true, ";") + "\n";
            str_KetQua += jTaoKhaiBaoBienCS(i_CapDo, jPKB_KhaiBao.getGiaTriTraVe(), true, ";")   ;
        //Gọi hàm nhập thông tin các tham số
            str_KetQua += "\n";
            ArrayList<jClass_Bien> jB_CacThamSo =jPKB_KhaiBao.getCacThamSo();
            if (jB_CacThamSo.get(0).getKieuDuLieu().contains("*")){
                 jClass_Bien jB_Bien = jB_CacThamSo.get(1);
                 str_KetQua += jTaoCapDo(i_CapDo) + jTaoChuoiThongBaoNhapCSharp(jB_Bien);
                 str_KetQua += jTaoCapDo(i_CapDo) + jB_Bien.getTen().trim()+" = Console.ReadLine();\n";
            }
            str_KetQua += jTaoCapDo(i_CapDo) + "nhapCacThamSo_"+ jPKB_KhaiBao.getTenHam() +"(";
            //Dua cac tham so vao loi goi ham
            for (int i = 0; i < jPKB_KhaiBao.getCacThamSo().size(); i++){
                jClass_Bien jB_Bien = jPKB_KhaiBao.getCacThamSo().get(i);
                str_KetQua += "ref ";
                str_KetQua += jB_Bien.getTen();
                if (i != jPKB_KhaiBao.getCacThamSo().size() - 1)
                    str_KetQua += ", ";
            }
            //Tạo dấu ");" và xuống dòng;
            str_KetQua += ");\n";
            str_KetQua += jTaoCapDo(i_CapDo)+ "if (KiemTraDuLieuNhap_"+ jPKB_KhaiBao.getTenHam()+"(";
              for (jClass_Bien bien : jPKB_KhaiBao.getCacThamSo()){
                //Thêm kiểu dữ liệu và ' '
               // str_KetQua += jClass_BoTaoCode.jChuyenKieuDuLieu(bien.getKieuDuLieu()) + " ";
                //Thêm tên biến và ", "
                str_KetQua += bien.getTen() + ","+
                        " ";
            //ví dụ đoạn code hiện tại "int (int a, "
               }
              if (str_KetQua.contains("," + " ")){
                 str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf("," +
                    " "));
             }

        //Thêm ') '
        str_KetQua += ")";
        //}
        str_KetQua += " == true)\n";
            //ví dụ đoạn code hiện tại "int (int a, "

            str_KetQua +=  jTaoCapDo(i_CapDo + 1) + jPKB_KhaiBao.getGiaTriTraVe().getTen() + " = " + jPKB_KhaiBao.getTenHam() ;
             str_KetQua += "(";
             for (jClass_Bien bien : jPKB_KhaiBao.getCacThamSo()){
                //Thêm kiểu dữ liệu và ' '
               // str_KetQua += jClass_BoTaoCode.jChuyenKieuDuLieu(bien.getKieuDuLieu()) + " ";
                //Thêm tên biến và ", "
                str_KetQua += bien.getTen() + ","+
                        " ";
            //ví dụ đoạn code hiện tại "int (int a, "
               }
              if (str_KetQua.contains("," + " ")){
                 str_KetQua = str_KetQua.substring(0, str_KetQua.lastIndexOf("," +
                    " "));
             }

             str_KetQua += ");\n";
             str_KetQua += jTaoCapDo(i_CapDo)+"else \n "+jTaoCapDo(i_CapDo + 1)+"Console.Write(\"Du lieu nhap khong hop le!\");\n";
        //Gọi hàm xuất giá trị các tham số
             str_KetQua += jTaoCapDo(i_CapDo) + "xuatKetQua_"+jPKB_KhaiBao.getTenHam()+ "(";
            //Dua cac tham so vao loi goi ham
            str_KetQua += _phanDacTa.getPhanKhaiBao().getGiaTriTraVe().getTen();
            //Tạo dấu ");" và xuống dòng;
            str_KetQua += ");\n";
            str_KetQua += jTaoCapDo(i_CapDo) + "return;\n";
        //Giảm cấp độ
        i_CapDo --;
        //Thêm dấu "}"
        str_KetQua += jTaoCapDo(i_CapDo) + "}";
        return str_KetQua;

    }
        public static String jTaoCodeCSharp (jClass_PhanDacTa jPKB_DacTa){
        _phanDacTa = jPKB_DacTa;
        jClass_PhanKhaiBao jPKB_KhaiBao = _phanDacTa.getPhanKhaiBao();
        String str_KetQua = "";
        //Tạo biến lưu lại cấp độ của dòng hiện tại (dùng cho việc lui vào khi tạo code)
        //Trước mỗi dòng code phải in ra cấp độ thích hợp của dòng đó
        int i_CapDo = 0;
        //Tạo hàm nhập giá trị các tham số
        str_KetQua += jTaoHamNhapCacThamSoCSharp(jPKB_KhaiBao.getCacThamSo(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        //Tạo hàm xuất giá trị các tham số
        str_KetQua += jTaoHamXuatCacThamSoCSharp(jPKB_KhaiBao.getCacThamSo(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        //Tạo hàm xuất ketqua
        str_KetQua += jTaoHamXuatKetQuaCSharp(jPKB_KhaiBao.getGiaTriTraVe(), i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();
        //Ham main
        str_KetQua += jTaoHamMainCSharp(jPKB_KhaiBao, i_CapDo);
        str_KetQua += jEnum_ThongTinBoSung.KhoangCachGiuaCacPhan.value();

        return str_KetQua;

    }


}